import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Aluno implements Usuario {
	private String nome;
	private String id;
	private static final int PRAZO_LIVRO = 7;
	private static final int PRAZO_REVISTA = 2;
	private List<Documento> listaDocumentos;
	private List<Documento> listaDevolvidos;
	private List<Date> listaDatasDevolucoes;

	public Aluno(String nome, String id) {
		this.nome = nome;
		this.id = id;
		listaDocumentos = new ArrayList<Documento>();
		listaDevolvidos = new ArrayList<Documento>();
		listaDatasDevolucoes = new ArrayList<Date>();
	}

	private int diasEntre(Date d, Date d2) {
		int anosEmDias = (d2.getYear() - d.getYear()) * 360;
		int mesesEmDias = (d2.getMonth() - d.getMonth()) * 30;
		return d2.getDay() - d.getDay() + anosEmDias + mesesEmDias;

	}

	public boolean devolverDocumento(Documento documento) {
		if (estaComDocumento(documento)) {
			this.listaDocumentos.remove(documento);
			documento.devolver();
			this.listaDevolvidos.add(documento);
			this.listaDatasDevolucoes.add(new Date());
			if(pagarMulta(documento)){
				System.out.println("O usuario entregou o documento com atraso. A multa eh de " + getMulta(documento));
			}else{
				System.out.println("O usuario entregou o documento no prazo certo.");
			}
			return true;
		}
		return false;
	}

	public void documentosComUsuario() {
		for (int i = 0; i < listaDocumentos.size(); i++) {
			System.out.println("Titulo: " + listaDocumentos.get(i).getTitulo());
		}
	}

	public boolean estaComDocumento(Documento documento) {
		return listaDocumentos.contains(documento);
	}

	public String getNome() {
		return this.nome;
	}

	public boolean pegarDocumento(Documento documento) {
		if (!documento.isEmprestado() && podePegarDocumento(documento)) {
			listaDocumentos.add(documento);
			documento.emprestar();
			return true;
		}
		return false;
	}

	public boolean podePegarDocumento(Documento documento) {
		if (listaDevolvidos.contains(documento)) {
			Date hoje = new Date();
			Date diaDevolucao = listaDatasDevolucoes.get(listaDevolvidos
					.indexOf(documento));
			if (diasEntre(hoje, diaDevolucao) < 30) {
				return false;
			}
		}
		return true;
	}

	public double getMulta(Documento documento) {
		if (listaDevolvidos.contains(documento)) {
			Date diaDevolvido = listaDatasDevolucoes.get(listaDevolvidos
					.indexOf(documento));
			Date diaRecebido = listaDevolvidos.get(
					listaDevolvidos.indexOf(documento)).getData();

			if (documento instanceof Livro) {
				if (diasEntre(diaRecebido, diaDevolvido) == (PRAZO_LIVRO + 1)
						|| diasEntre(diaRecebido, diaDevolvido) == (PRAZO_LIVRO + 2)) {
					return 0.5;
				}

				if (diasEntre(diaRecebido, diaDevolvido) > (PRAZO_LIVRO + 2)
						&& diasEntre(diaRecebido, diaDevolvido) <= (PRAZO_LIVRO + 14)) {
					return 2;
				}

				if (diasEntre(diaRecebido, diaDevolvido) >= (PRAZO_LIVRO + 15)
						&& diasEntre(diaRecebido, diaDevolvido) <= (PRAZO_LIVRO + 30)) {
					return 3;
				}

				if (diasEntre(diaRecebido, diaDevolvido) > (PRAZO_LIVRO + 30)) {
					return 5;
				}
			}
			if (documento instanceof Revista) {
				if (diasEntre(diaRecebido, diaDevolvido) == (PRAZO_REVISTA + 1)
						|| diasEntre(diaRecebido, diaDevolvido) == (PRAZO_REVISTA + 2)) {
					return 0.3;
				}

				if (diasEntre(diaRecebido, diaDevolvido) > (PRAZO_REVISTA + 2)
						&& diasEntre(diaRecebido, diaDevolvido) <= (PRAZO_REVISTA + 14)) {
					return 1;
				}

				if (diasEntre(diaRecebido, diaDevolvido) >= (PRAZO_REVISTA + 15)
						&& diasEntre(diaRecebido, diaDevolvido) <= (PRAZO_REVISTA + 30)) {
					return 2;
				}

				if (diasEntre(diaRecebido, diaDevolvido) > (PRAZO_REVISTA + 30)) {
					return 3;
				}
			}
		}
		return 0;
	}

	public boolean pagarMulta(Documento documento) {
		if (getMulta(documento) == 0) {
			return false;
		}
		return true;
	}

	public boolean temDocumentos() {
		return listaDocumentos.size() != 0; 
	}

	@Override
	public String getId() {
		return id;
	}

}
